<template>
  <div class="lcd-design-view">
    <ul class="lcd-dv-header">
      <li style="float: left; width: 260px; text-align: center">
        <img src="/img/logo.png" width="36" height="36" style="vertical-align: -12px; cursor: pointer" @click="$router.push('/')"/>
        <span style="font-size: 18px; color: #000000; margin-left: 10px;">低代码设计平台(开发版)</span>
      </li>
      <li v-if="$route.path=='/lcd/design'" style="float: right; min-width: 300px; text-align: center">
        <span style="margin-left: 12px; padding-right: 32px">
          <ArrowLeftOutlined title="返回" :style="{fontSize: '18px', cursor: 'pointer'}" @click="backHandle" />
          <ivz-icon title="sql管理" type="iz-icon-sql" :style="{fontSize: '20px', marginLeft: '16px', cursor: 'pointer'}" @click="sqlClickHandle" />
          <ivz-icon title="重置" type="iz-icon-freshen" :style="{fontSize: '20px', marginLeft: '16px', cursor: 'pointer'}" @click="resetHandle" />
          <ivz-icon title="保存" type="iz-icon-submit" :style="{fontSize: '22px', marginLeft: '16px', cursor: 'pointer'}" @click="submitHandle" />
          <ivz-icon title="预览" type="iz-icon-preview" :style="{fontSize: '18px', marginLeft: '16px', cursor: 'pointer'}" @click="previewHandle" />
        </span>
      </li>
    </ul>
    <AModal :visible="sqlVisible" @cancel="sqlManageCancel" title="" width="920px" :bodyStyle="{padding: '3px', height: '420px'}"
            :closable="false" wrapClassName="lcd-dv-modal" :footer="null">
      <ATable :bordered="true" size="small" :columns="sqlManager.columns" :scroll="{y: 210}" :dataSource="sqlData" :pagination="false" rowKey="name">
        <template #default="{record}">
          <AInput size="small" v-model:value="record.default" :disabled="record.dd" allowClear @change="(e) => handleSqlScriptChange(e.target.value, record)"/>
        </template>
        <template #type="{record}">
          <a-auto-complete v-model:value="record.type" :options="typeOptions" allowClear
                   @search="typeSearch" :disabled="record.td" @change="(val) => handleSqlScriptChange(val, record, 'fieldType')"/>
        </template>
        <template #index="{record}">
          <AInput size="small" v-model:value="record.index" :disabled="record.ind" allowClear @change="(e) => handleSqlScriptChange(e.target.value, record, 'index')"/>
        </template>
        <template #comment="{record}">
          <AInput size="small" v-model:value="record.comment" @change="(e) => handleSqlScriptChange(e.target.value, record, 'comment')"/>
        </template>
        <template #primary="{record}">
          <ACheckbox size="small" v-model:checked="record.primary" :disabled="record.pd" @change="(val) => handleSqlScriptChange(val, record)"/>
        </template>
        <template #unique="{record}">
          <ACheckbox size="small" v-model:checked="record.unique" :disabled="record.ud" @change="(e) => handleSqlScriptChange(e.target.checked, record, 'unique')"/>
        </template>
        <template #auto="{record}">
          <ACheckbox size="small" v-model:checked="record.auto" :disabled="record.ad" @change="(val) => handleSqlScriptChange(val, record)"/>
        </template>
        <template #notNull="{record}">
          <ACheckbox size="small" v-model:checked="record.notNull" :disabled="record.nd" @change="(e) => handleSqlScriptChange(e.target.checked, record, 'notNull')"/>
        </template>
      </ATable>
      <div style="margin-top: 3px">
        <span style="display: inline-block; width: 100%; background: #efefef; padding: 3px; font-size: 14px">
          sql script <label style="color: orange; margin-left: 5px; font-size: 12px; ">注：索引名相同的将变成联合索引(主键)</label>
        </span>
        <pre style="height: 152px; overflow-y: auto">{{sqlScript}}</pre>
      </div>
    </AModal>
    <div class="lcd-dv-body">
      <router-view />
      <IvzPreview />
    </div>
  </div>
</template>

<script>
import {mapGetters, mapMutations, mapState, useStore} from "vuex";
import {reactive, ref} from "vue";
import {MysqlDataType} from "@/components/OptionsMetaData";
import MetaUtils from "@/utils/MetaUtils";
import {SqlParser} from "@/metas/SqlParser";
import IvzPreview from "@/components/preview/IvzPreview.vue";
import {IvzoneParser} from "@/metas/IvzoneParser";
import {ArrowLeftOutlined} from "@ant-design/icons-vue";

export default {
  name: "index",
  components: {IvzPreview, ArrowLeftOutlined},
  setup() {
    let store = useStore();
    let sqlManager = reactive({
      columns: [
        {dataIndex: 'name', title: '字段名(双击定位)', width: 138, align: 'center', customCell(column) {
            return {class: 'lcd-dvr-name', onDblclick: (e) => {
              let editMetas = store.getters['editMetas'];
                let metaById = MetaUtils.getMetaById(editMetas, column.id);
                if(metaById) {
                  store.commit('switchActiveMetaTo',metaById);
                  store.commit('switchSqlVisible', false);
                  store.commit('switchEditVisible', true);
                } else {
                  let containerMeta = store.getters['containerMeta'];
                  store.commit('switchSqlVisible', false);
                  store.commit('switchActiveMetaTo',containerMeta);
                }
              }
            }
          }
        },
        {dataIndex: 'type', title: '类型', width: 110, align: 'center', slots: {customRender: 'type'}},
        {dataIndex: 'default', title: '默认值', width: 100, align: 'center', slots: {customRender: 'default'}},
        {dataIndex: 'index', title: '索引名', width: 168, align: 'center', slots: {customRender: 'index'}},
        {dataIndex: 'primary', title: '主键', width: 50, align: 'center', slots: {customRender: 'primary'}},
        {dataIndex: 'unique', title: '唯一', width: 50, align: 'center', slots: {customRender: 'unique'}},
        {dataIndex: 'auto', title: '自增', width: 50, align: 'center', slots: {customRender: 'auto'}},
        {dataIndex: 'notNull', title: '非空', width: 50, align: 'center', slots: {customRender: 'notNull'}},
        {dataIndex: 'comment', title: '说明', align: 'center', slots: {customRender: 'comment'}},
      ]
    })
    let typeOptions = ref(MysqlDataType)
    return {sqlManager, typeOptions}
  },
  computed: {
    ...mapState(['preview']),
    ...mapGetters(['sqlVisible', 'sqlScript', 'sqlData', 'editMetas', 'containerMeta', 'isReset'])
  },
  watch: {
    sqlVisible(newVal) {
      if(newVal) {
        this.initSqlScript();
      }
    }
  },
  created() {},
  methods: {
    ...mapMutations(['switchSqlVisible', 'setSqlScript', 'setSqlData', 'resetSys', 'switchPreviewTo']),
    backHandle() {
      this.$router.push("/lcd")
    },
    previewHandle() {
      this.switchPreviewTo(!this.preview.status)
    },
    sqlClickHandle() {
      this.switchSqlVisible(true);
    },
    resetHandle() {
      this.$msg.confirm("确定重置？", "重置后数据将会恢复到最初状态, 请确认").then(() => {
        this.$router.replace("refresh").then(() => this.resetSys())
      }). catch(reason => null);
    },
    submitHandle() {
      this.initSqlScript();

      let edit = this.$store.state['edit'];
      let formTable = this.$store.state['table'];
      let search = this.$store.state['search'];
      let global = this.$store.state['global'];
      let container = this.$store.state['container'];
      let sqlManager = this.$store.state['sqlManager']
      let sqlScript = sqlManager.sqlScript;

      // ivzone组件解析
      let ivzoneParser = new IvzoneParser();
      let editComponent = ivzoneParser.resolveEdit(edit);
      let tableComponent = ivzoneParser.resolveTable(formTable);
      let searchComponent = ivzoneParser.resolveSearch(edit, search);
      let ivzone = {edit: editComponent, search: searchComponent, table: tableComponent}


      let name = this.containerMeta.tabModel['name'];
      let comment = this.containerMeta.tabModel['comment'];
      let tableName = this.containerMeta.tabModel['tableName'];

      let messageType = this.$msg.loadingMessage("保存中...", 0);
      let id = this.$store.state['id'];
      if(id) {
        this.$http.post("/lcd/design/edit", {id, edit, formTable, search, container, global, name, comment, tableName, sqlScript, ivzone}).then(resp => {
          if(resp['code'] == 200) {
            this.$msg.successMessage("编辑成功");
          } else {
            this.$msg.warningMessage(resp.message);
          }
        }).catch(reason => console.error(reason)).finally(() => messageType())
      } else {
        this.$http.post("/lcd/design/add", {edit, formTable, search, container, global, name, comment, tableName, sqlScript, ivzone}).then(resp => {
          if(resp['code'] == 200) {
            this.$store.state['id'] = resp.data;
            this.$msg.successMessage("保存成功");
          } else {
            this.$msg.warningMessage(resp.message);
          }
        }).catch(reason => console.error(reason)).finally(() => messageType())
      }
    },
    sqlManageCancel() {
      this.switchSqlVisible(false);
    },
    typeSearch(value) {
      this.typeOptions = value ? MysqlDataType.filter(item => item.value.includes(value)) : MysqlDataType;
    },
    initSqlScript() {
      let tableName = this.containerMeta.tabModel['tableName'];
      let comment = this.containerMeta.tabModel['comment'];
      let keyField = this.containerMeta.tabModel['keyField'];
      let keyType = this.containerMeta.tabModel['keyType'];

      let sqlData = this.editMetas.filter(item => item.tabModel['isDb']).map(item => {
        let model = item.tabModel;
        return reactive({id: item.id, name: model.field, type: model.fieldType, pd: keyField ? true : false
          , td: false, unique: model.unique, notNull: model.notNull, index: model.index, comment: model.comment})
      });

      if(keyField) {
        let primary = reactive({name: keyField, type: keyType, primary: true, auto: keyType == 'uuid' ? false : true,
          unique: false, notNull: true, pd: true, ud: true, ad: true, nd: true, ind: true, dd: true, td: true, comment: null, id: 'primary'});
        sqlData.splice(0, 0, primary)
      }

      let sqlScript = new SqlParser(tableName, comment).resolve(sqlData);
      this.setSqlData(sqlData);
      this.setSqlScript(sqlScript);
    },
    handleSqlScriptChange(val, record, type) {
      let comment = this.containerMeta.tabModel['comment'];
      let tableName = this.containerMeta.tabModel['tableName'];

      // 数据同步到编辑表单
      if(type) {
        let metaById = MetaUtils.getMetaById(this.editMetas, record.id);
        if(metaById) {
          metaById.tabModel[type] = val;
          if(type == 'unique' || type == 'notNull') {
            metaById.tabModel['tableAttrs'] = record.unique && record.notNull
                ? ['unique', 'notNull'] : record.unique
                    ? ['unique'] : record.notNull
                        ? ['notNull'] : [];
          }
        }
      }

      // 解析sql脚本
      let sqlScript = new SqlParser(tableName, comment).resolve(this.sqlData);
      this.setSqlScript(sqlScript);
    }
  }
}
</script>

<style>
.lcd-design-view {
  width: 100%;
  height: 100%;
  display: flex;
  overflow: hidden;
  display: -ms-flex;
  display: -webkit-flex;
  flex-direction: column;
  justify-content: space-between;
}
.lcd-dv-header {
  height: 52px;
  margin: 0px;
  padding: 0px;
  list-style: none;
  line-height: 52px;
  box-shadow: 0px 1px 4px 1px #cccccc;
}
.lcd-dv-body {
  height: 100%;
  margin-top: 8px;
  overflow-y: auto;
  position: relative;
}
.lcd-dvr-name {
  cursor: pointer;
}
.lcd-dv-modal .ant-table.ant-table-small > .ant-table-content > .ant-table-scroll > .ant-table-body > table > .ant-table-tbody > tr > td {
  padding: 3px;
}
.lcd-dv-modal .ant-select-auto-complete .ant-select-selection-search-input {
  padding: 0px 3px;
}
</style>